x86 mce: Small fix for polling/CMCI race conditions.
authorKeir Fraser <keir.fraser@citrix.com>
Mon, 6 Apr 2009 12:46:11 +0000 (13:46 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Mon, 6 Apr 2009 12:46:11 +0000 (13:46 +0100)
When CMCI happens very quickly, polling/CMCI processing path might
cross. For Intel CPUs which support CMCI, if the error bank has CMCI
capability, we'll disable poll on this bank.

Signed-off-by: Liping Ke <liping.ke@intel.com>
Signed-off-by: Yunhong Jiang<yunhong.jiang@intel.com>
xen/arch/x86/cpu/mcheck/mce.c
xen/arch/x86/cpu/mcheck/mce.h
xen/arch/x86/cpu/mcheck/mce_intel.c
xen/arch/x86/cpu/mcheck/non-fatal.c

index bc18e3048b868673c9a8ee9e58094893a66ff541..a43f2f131afeb5b0a4af80ed8ad546d13922efea 100644 (file)
@@ -577,6 +577,7 @@ void mcheck_init(struct cpuinfo_x86 *c)
                break;
        }
 
+    set_poll_bankmask(c);
        if (!inited)
                printk(XENLOG_INFO "CPU%i: No machine check initialization\n",
                    smp_processor_id());
@@ -1230,7 +1231,19 @@ long do_mca(XEN_GUEST_HANDLE(xen_mc_t) u_xen_mc)
 
        return ret;
 }
+void set_poll_bankmask(struct cpuinfo_x86 *c)
+{
 
+    if (cmci_support && !mce_disabled) {
+        memcpy(&(__get_cpu_var(poll_bankmask)),
+                &(__get_cpu_var(no_cmci_banks)), sizeof(cpu_banks_t));
+    }
+    else {
+        memcpy(&(get_cpu_var(poll_bankmask)), &mca_allbanks, sizeof(cpu_banks_t));
+        if (mce_firstbank(c))
+            clear_bit(0, get_cpu_var(poll_bankmask));
+    }
+}
 void mc_panic(char *s)
 {
     console_start_sync();
index 2bd6f023d6338011f391c3d08131e1ad63fea1c4..6b79e673e26a606797c1c4056bbc1082b90ddfca 100644 (file)
@@ -88,6 +88,10 @@ struct mca_summary {
 };
 
 extern cpu_banks_t mca_allbanks;
+void set_poll_bankmask(struct cpuinfo_x86 *c);
+DECLARE_PER_CPU(cpu_banks_t, poll_bankmask);
+DECLARE_PER_CPU(cpu_banks_t, no_cmci_banks);
+extern int cmci_support;
 
 extern mctelem_cookie_t mcheck_mca_logout(enum mca_source, cpu_banks_t,
     struct mca_summary *);
index d8fa0ebb07eb4653848a34d3222346b670db4327..67d0342d99d575b4f75c3f0d5cf8d1bec95816c1 100644 (file)
 #include "x86_mca.h"
 
 DEFINE_PER_CPU(cpu_banks_t, mce_banks_owned);
+DEFINE_PER_CPU(cpu_banks_t, no_cmci_banks);
+int cmci_support = 0;
 
 static int nr_intel_ext_msrs = 0;
-static int cmci_support = 0;
 static int firstbank;
 
 #ifdef CONFIG_X86_MCE_THERMAL
@@ -548,7 +549,6 @@ static void intel_machine_check(struct cpu_user_regs * regs, long error_code)
 }
 
 static DEFINE_SPINLOCK(cmci_discover_lock);
-static DEFINE_PER_CPU(cpu_banks_t, no_cmci_banks);
 
 /*
  * Discover bank sharing using the algorithm recommended in the SDM.
index 167b1cea2a837ed0ede24026b8a3bd2c11973579..9d66a12b6b981947c749338267eed05552353913 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "mce.h"
 
-static cpu_banks_t bankmask;
+DEFINE_PER_CPU(cpu_banks_t, poll_bankmask);
 static struct timer mce_timer;
 
 #define MCE_PERIOD MILLISECS(8000)
@@ -39,7 +39,7 @@ static void mce_checkregs (void *info)
        struct mca_summary bs;
        static uint64_t dumpcount = 0;
 
-       mctc = mcheck_mca_logout(MCA_POLLER, bankmask, &bs);
+       mctc = mcheck_mca_logout(MCA_POLLER, __get_cpu_var(poll_bankmask), &bs);
 
        if (bs.errcnt && mctc != NULL) {
                adjust++;
@@ -94,10 +94,6 @@ static int __init init_nonfatal_mce_checker(void)
        if (!mce_available(c))
                return -ENODEV;
 
-       memcpy(&bankmask, &mca_allbanks, sizeof (cpu_banks_t));
-       if (mce_firstbank(c) == 1)
-               clear_bit(0, bankmask);
-
        /*
         * Check for non-fatal errors every MCE_RATE s
         */